/*
 * Copyright 2022 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.seppiko.chart.utils

import com.d_project.qrcode.ErrorCorrectionLevel
import com.d_project.qrcode.GIFImage
import com.d_project.qrcode.QRCode
import com.google.zxing.qrcode.encoder.ByteMatrix
import java.lang.IllegalArgumentException

/**
 * D_Project util
 *
 * @author Leonard Woo
 */
object DProjectUtil {

  fun getQRCode(text: String?, typeNumber: Int, errorCorrectionLevel: Int): QRCode {
    return if (typeNumber == 0) {
      QRCode.getMinimumQRCode(text, errorCorrectionLevel)
    } else {
      val qr = QRCode()
      qr.typeNumber = typeNumber
      qr.errorCorrectionLevel = errorCorrectionLevel
      qr.addData(text)
      qr.make()
      qr
    }
  }

  fun parseErrorCorrectionLevel(ecl: String): Int {
    return if ("L".equals(ecl, ignoreCase = true)) {
      ErrorCorrectionLevel.L
    } else if ("Q".equals(ecl, ignoreCase = true)) {
      ErrorCorrectionLevel.Q
    } else if ("M".equals(ecl, ignoreCase = true)) {
      ErrorCorrectionLevel.M
    } else if ("H".equals(ecl, ignoreCase = true)) {
      ErrorCorrectionLevel.H
    } else {
      throw IllegalArgumentException("invalid error correct level : $ecl")
    }
  }

  fun createGIFImage(qrcode: QRCode, cellSize: Int, margin: Int): GIFImage {
    val imageSize = qrcode.moduleCount * cellSize + margin * 2
    val image = GIFImage(imageSize, imageSize)
    for (y in 0 until imageSize) {
      for (x in 0 until imageSize) {
        if (margin <= x && x < imageSize - margin && margin <= y && y < imageSize - margin) {
          val col = (x - margin) / cellSize
          val row = (y - margin) / cellSize
          if (qrcode.isDark(row, col)) {
            image.setPixel(x, y, 0)
          } else {
            image.setPixel(x, y, 1)
          }
        } else {
          image.setPixel(x, y, 1)
        }
      }
    }
    return image
  }

  fun convertToZxingByteMatrix(qrcode: QRCode): ByteMatrix {
    val output = ByteMatrix(qrcode.moduleCount, qrcode.moduleCount)
    for (row in 0 until qrcode.moduleCount) {
      for (col in 0 until qrcode.moduleCount) {
        if (qrcode.isDark(row, col)) {
          output[col, row] = 1
        }
      }
    }
    return output
  }
}